import * as fs from "fs";
import * as path from "path";
import * as querystring from 'query-string';
import * as errors from "./errors.mjs";
import { getEncryptionHeaders, isEmpty, isEmptyObject, isNumber, isObject, isString, isValidBucketName, isValidObjectName } from "./internal/helper.mjs";
import { RETENTION_MODES } from "./internal/type.mjs";
export { ENCRYPTION_TYPES, LEGAL_HOLD_STATUS, RETENTION_MODES, RETENTION_VALIDITY_UNITS } from "./internal/type.mjs";
export const DEFAULT_REGION = 'us-east-1';
export class CopySourceOptions {
  constructor({
    Bucket,
    Object,
    VersionID = '',
    MatchETag = '',
    NoMatchETag = '',
    MatchModifiedSince = null,
    MatchUnmodifiedSince = null,
    MatchRange = false,
    Start = 0,
    End = 0,
    Encryption = undefined
  }) {
    this.Bucket = Bucket;
    this.Object = Object;
    this.VersionID = VersionID;
    this.MatchETag = MatchETag;
    this.NoMatchETag = NoMatchETag;
    this.MatchModifiedSince = MatchModifiedSince;
    this.MatchUnmodifiedSince = MatchUnmodifiedSince;
    this.MatchRange = MatchRange;
    this.Start = Start;
    this.End = End;
    this.Encryption = Encryption;
  }
  validate() {
    if (!isValidBucketName(this.Bucket)) {
      throw new errors.InvalidBucketNameError('Invalid Source bucket name: ' + this.Bucket);
    }
    if (!isValidObjectName(this.Object)) {
      throw new errors.InvalidObjectNameError(`Invalid Source object name: ${this.Object}`);
    }
    if (this.MatchRange && this.Start !== -1 && this.End !== -1 && this.Start > this.End || this.Start < 0) {
      throw new errors.InvalidObjectNameError('Source start must be non-negative, and start must be at most end.');
    } else if (this.MatchRange && !isNumber(this.Start) || !isNumber(this.End)) {
      throw new errors.InvalidObjectNameError('MatchRange is specified. But Invalid Start and End values are specified.');
    }
    return true;
  }
  getHeaders() {
    const headerOptions = {};
    headerOptions['x-amz-copy-source'] = encodeURI(this.Bucket + '/' + this.Object);
    if (!isEmpty(this.VersionID)) {
      headerOptions['x-amz-copy-source'] = `${encodeURI(this.Bucket + '/' + this.Object)}?versionId=${this.VersionID}`;
    }
    if (!isEmpty(this.MatchETag)) {
      headerOptions['x-amz-copy-source-if-match'] = this.MatchETag;
    }
    if (!isEmpty(this.NoMatchETag)) {
      headerOptions['x-amz-copy-source-if-none-match'] = this.NoMatchETag;
    }
    if (!isEmpty(this.MatchModifiedSince)) {
      headerOptions['x-amz-copy-source-if-modified-since'] = this.MatchModifiedSince;
    }
    if (!isEmpty(this.MatchUnmodifiedSince)) {
      headerOptions['x-amz-copy-source-if-unmodified-since'] = this.MatchUnmodifiedSince;
    }
    return headerOptions;
  }
}

/**
 * @deprecated use nodejs fs module
 */
export function removeDirAndFiles(dirPath, removeSelf = true) {
  if (removeSelf) {
    return fs.rmSync(dirPath, {
      recursive: true,
      force: true
    });
  }
  fs.readdirSync(dirPath).forEach(item => {
    fs.rmSync(path.join(dirPath, item), {
      recursive: true,
      force: true
    });
  });
}
export class CopyDestinationOptions {
  constructor({
    Bucket,
    Object,
    Encryption,
    UserMetadata,
    UserTags,
    LegalHold,
    RetainUntilDate,
    Mode,
    MetadataDirective
  }) {
    this.Bucket = Bucket;
    this.Object = Object;
    this.Encryption = Encryption ?? undefined; // null input will become undefined, easy for runtime assert
    this.UserMetadata = UserMetadata;
    this.UserTags = UserTags;
    this.LegalHold = LegalHold;
    this.Mode = Mode; // retention mode
    this.RetainUntilDate = RetainUntilDate;
    this.MetadataDirective = MetadataDirective;
  }
  getHeaders() {
    const replaceDirective = 'REPLACE';
    const headerOptions = {};
    const userTags = this.UserTags;
    if (!isEmpty(userTags)) {
      headerOptions['X-Amz-Tagging-Directive'] = replaceDirective;
      headerOptions['X-Amz-Tagging'] = isObject(userTags) ? querystring.stringify(userTags) : isString(userTags) ? userTags : '';
    }
    if (this.Mode) {
      headerOptions['X-Amz-Object-Lock-Mode'] = this.Mode; // GOVERNANCE or COMPLIANCE
    }

    if (this.RetainUntilDate) {
      headerOptions['X-Amz-Object-Lock-Retain-Until-Date'] = this.RetainUntilDate; // needs to be UTC.
    }

    if (this.LegalHold) {
      headerOptions['X-Amz-Object-Lock-Legal-Hold'] = this.LegalHold; // ON or OFF
    }

    if (this.UserMetadata) {
      for (const [key, value] of Object.entries(this.UserMetadata)) {
        headerOptions[`X-Amz-Meta-${key}`] = value.toString();
      }
    }
    if (this.MetadataDirective) {
      headerOptions[`X-Amz-Metadata-Directive`] = this.MetadataDirective;
    }
    if (this.Encryption) {
      const encryptionHeaders = getEncryptionHeaders(this.Encryption);
      for (const [key, value] of Object.entries(encryptionHeaders)) {
        headerOptions[key] = value;
      }
    }
    return headerOptions;
  }
  validate() {
    if (!isValidBucketName(this.Bucket)) {
      throw new errors.InvalidBucketNameError('Invalid Destination bucket name: ' + this.Bucket);
    }
    if (!isValidObjectName(this.Object)) {
      throw new errors.InvalidObjectNameError(`Invalid Destination object name: ${this.Object}`);
    }
    if (!isEmpty(this.UserMetadata) && !isObject(this.UserMetadata)) {
      throw new errors.InvalidObjectNameError(`Destination UserMetadata should be an object with key value pairs`);
    }
    if (!isEmpty(this.Mode) && ![RETENTION_MODES.GOVERNANCE, RETENTION_MODES.COMPLIANCE].includes(this.Mode)) {
      throw new errors.InvalidObjectNameError(`Invalid Mode specified for destination object it should be one of [GOVERNANCE,COMPLIANCE]`);
    }
    if (this.Encryption !== undefined && isEmptyObject(this.Encryption)) {
      throw new errors.InvalidObjectNameError(`Invalid Encryption configuration for destination object `);
    }
    return true;
  }
}

/**
 * maybe this should be a generic type for Records, leave it for later refactor
 */
export class SelectResults {
  constructor({
    records,
    // parsed data as stream
    response,
    // original response stream
    stats,
    // stats as xml
    progress // stats as xml
  }) {
    this.records = records;
    this.response = response;
    this.stats = stats;
    this.progress = progress;
  }
  setStats(stats) {
    this.stats = stats;
  }
  getStats() {
    return this.stats;
  }
  setProgress(progress) {
    this.progress = progress;
  }
  getProgress() {
    return this.progress;
  }
  setResponse(response) {
    this.response = response;
  }
  getResponse() {
    return this.response;
  }
  setRecords(records) {
    this.records = records;
  }
  getRecords() {
    return this.records;
  }
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJmcyIsInBhdGgiLCJxdWVyeXN0cmluZyIsImVycm9ycyIsImdldEVuY3J5cHRpb25IZWFkZXJzIiwiaXNFbXB0eSIsImlzRW1wdHlPYmplY3QiLCJpc051bWJlciIsImlzT2JqZWN0IiwiaXNTdHJpbmciLCJpc1ZhbGlkQnVja2V0TmFtZSIsImlzVmFsaWRPYmplY3ROYW1lIiwiUkVURU5USU9OX01PREVTIiwiRU5DUllQVElPTl9UWVBFUyIsIkxFR0FMX0hPTERfU1RBVFVTIiwiUkVURU5USU9OX1ZBTElESVRZX1VOSVRTIiwiREVGQVVMVF9SRUdJT04iLCJDb3B5U291cmNlT3B0aW9ucyIsImNvbnN0cnVjdG9yIiwiQnVja2V0IiwiT2JqZWN0IiwiVmVyc2lvbklEIiwiTWF0Y2hFVGFnIiwiTm9NYXRjaEVUYWciLCJNYXRjaE1vZGlmaWVkU2luY2UiLCJNYXRjaFVubW9kaWZpZWRTaW5jZSIsIk1hdGNoUmFuZ2UiLCJTdGFydCIsIkVuZCIsIkVuY3J5cHRpb24iLCJ1bmRlZmluZWQiLCJ2YWxpZGF0ZSIsIkludmFsaWRCdWNrZXROYW1lRXJyb3IiLCJJbnZhbGlkT2JqZWN0TmFtZUVycm9yIiwiZ2V0SGVhZGVycyIsImhlYWRlck9wdGlvbnMiLCJlbmNvZGVVUkkiLCJyZW1vdmVEaXJBbmRGaWxlcyIsImRpclBhdGgiLCJyZW1vdmVTZWxmIiwicm1TeW5jIiwicmVjdXJzaXZlIiwiZm9yY2UiLCJyZWFkZGlyU3luYyIsImZvckVhY2giLCJpdGVtIiwiam9pbiIsIkNvcHlEZXN0aW5hdGlvbk9wdGlvbnMiLCJVc2VyTWV0YWRhdGEiLCJVc2VyVGFncyIsIkxlZ2FsSG9sZCIsIlJldGFpblVudGlsRGF0ZSIsIk1vZGUiLCJNZXRhZGF0YURpcmVjdGl2ZSIsInJlcGxhY2VEaXJlY3RpdmUiLCJ1c2VyVGFncyIsInN0cmluZ2lmeSIsImtleSIsInZhbHVlIiwiZW50cmllcyIsInRvU3RyaW5nIiwiZW5jcnlwdGlvbkhlYWRlcnMiLCJHT1ZFUk5BTkNFIiwiQ09NUExJQU5DRSIsImluY2x1ZGVzIiwiU2VsZWN0UmVzdWx0cyIsInJlY29yZHMiLCJyZXNwb25zZSIsInN0YXRzIiwicHJvZ3Jlc3MiLCJzZXRTdGF0cyIsImdldFN0YXRzIiwic2V0UHJvZ3Jlc3MiLCJnZXRQcm9ncmVzcyIsInNldFJlc3BvbnNlIiwiZ2V0UmVzcG9uc2UiLCJzZXRSZWNvcmRzIiwiZ2V0UmVjb3JkcyJdLCJzb3VyY2VzIjpbImhlbHBlcnMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZnMgZnJvbSAnbm9kZTpmcydcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAnbm9kZTpwYXRoJ1xuXG5pbXBvcnQgKiBhcyBxdWVyeXN0cmluZyBmcm9tICdxdWVyeS1zdHJpbmcnXG5cbmltcG9ydCAqIGFzIGVycm9ycyBmcm9tICcuL2Vycm9ycy50cydcbmltcG9ydCB7XG4gIGdldEVuY3J5cHRpb25IZWFkZXJzLFxuICBpc0VtcHR5LFxuICBpc0VtcHR5T2JqZWN0LFxuICBpc051bWJlcixcbiAgaXNPYmplY3QsXG4gIGlzU3RyaW5nLFxuICBpc1ZhbGlkQnVja2V0TmFtZSxcbiAgaXNWYWxpZE9iamVjdE5hbWUsXG59IGZyb20gJy4vaW50ZXJuYWwvaGVscGVyLnRzJ1xuaW1wb3J0IHR5cGUgeyBFbmNyeXB0aW9uLCBPYmplY3RNZXRhRGF0YSwgUmVxdWVzdEhlYWRlcnMgfSBmcm9tICcuL2ludGVybmFsL3R5cGUudHMnXG5pbXBvcnQgeyBSRVRFTlRJT05fTU9ERVMgfSBmcm9tICcuL2ludGVybmFsL3R5cGUudHMnXG5cbmV4cG9ydCB7IEVOQ1JZUFRJT05fVFlQRVMsIExFR0FMX0hPTERfU1RBVFVTLCBSRVRFTlRJT05fTU9ERVMsIFJFVEVOVElPTl9WQUxJRElUWV9VTklUUyB9IGZyb20gJy4vaW50ZXJuYWwvdHlwZS50cydcblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfUkVHSU9OID0gJ3VzLWVhc3QtMSdcblxuZXhwb3J0IGludGVyZmFjZSBJQ29weVNvdXJjZU9wdGlvbnMge1xuICBCdWNrZXQ6IHN0cmluZ1xuICBPYmplY3Q6IHN0cmluZ1xuICAvKipcbiAgICogVmFsaWQgdmVyc2lvbklkXG4gICAqL1xuICBWZXJzaW9uSUQ/OiBzdHJpbmdcbiAgLyoqXG4gICAqIEV0YWcgdG8gbWF0Y2hcbiAgICovXG4gIE1hdGNoRVRhZz86IHN0cmluZ1xuICAvKipcbiAgICogRXRhZyB0byBleGNsdWRlXG4gICAqL1xuICBOb01hdGNoRVRhZz86IHN0cmluZ1xuICAvKipcbiAgICogTW9kaWZpZWQgRGF0ZSBvZiB0aGUgb2JqZWN0L3BhcnQuICBVVEMgRGF0ZSBpbiBzdHJpbmcgZm9ybWF0XG4gICAqL1xuICBNYXRjaE1vZGlmaWVkU2luY2U/OiBzdHJpbmcgfCBudWxsXG4gIC8qKlxuICAgKiBNb2RpZmllZCBEYXRlIG9mIHRoZSBvYmplY3QvcGFydCB0byBleGNsdWRlIFVUQyBEYXRlIGluIHN0cmluZyBmb3JtYXRcbiAgICovXG4gIE1hdGNoVW5tb2RpZmllZFNpbmNlPzogc3RyaW5nIHwgbnVsbFxuICAvKipcbiAgICogdHJ1ZSBvciBmYWxzZSBPYmplY3QgcmFuZ2UgdG8gbWF0Y2hcbiAgICovXG4gIE1hdGNoUmFuZ2U/OiBib29sZWFuXG4gIFN0YXJ0PzogbnVtYmVyXG4gIEVuZD86IG51bWJlclxuICBFbmNyeXB0aW9uPzogRW5jcnlwdGlvblxufVxuXG5leHBvcnQgY2xhc3MgQ29weVNvdXJjZU9wdGlvbnMge1xuICBwdWJsaWMgcmVhZG9ubHkgQnVja2V0OiBzdHJpbmdcbiAgcHVibGljIHJlYWRvbmx5IE9iamVjdDogc3RyaW5nXG4gIHB1YmxpYyByZWFkb25seSBWZXJzaW9uSUQ6IHN0cmluZ1xuICBwdWJsaWMgTWF0Y2hFVGFnOiBzdHJpbmdcbiAgcHJpdmF0ZSByZWFkb25seSBOb01hdGNoRVRhZzogc3RyaW5nXG4gIHByaXZhdGUgcmVhZG9ubHkgTWF0Y2hNb2RpZmllZFNpbmNlOiBzdHJpbmcgfCBudWxsXG4gIHByaXZhdGUgcmVhZG9ubHkgTWF0Y2hVbm1vZGlmaWVkU2luY2U6IHN0cmluZyB8IG51bGxcbiAgcHVibGljIHJlYWRvbmx5IE1hdGNoUmFuZ2U6IGJvb2xlYW5cbiAgcHVibGljIHJlYWRvbmx5IFN0YXJ0OiBudW1iZXJcbiAgcHVibGljIHJlYWRvbmx5IEVuZDogbnVtYmVyXG4gIHByaXZhdGUgcmVhZG9ubHkgRW5jcnlwdGlvbj86IEVuY3J5cHRpb25cblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgQnVja2V0LFxuICAgIE9iamVjdCxcbiAgICBWZXJzaW9uSUQgPSAnJyxcbiAgICBNYXRjaEVUYWcgPSAnJyxcbiAgICBOb01hdGNoRVRhZyA9ICcnLFxuICAgIE1hdGNoTW9kaWZpZWRTaW5jZSA9IG51bGwsXG4gICAgTWF0Y2hVbm1vZGlmaWVkU2luY2UgPSBudWxsLFxuICAgIE1hdGNoUmFuZ2UgPSBmYWxzZSxcbiAgICBTdGFydCA9IDAsXG4gICAgRW5kID0gMCxcbiAgICBFbmNyeXB0aW9uID0gdW5kZWZpbmVkLFxuICB9OiBJQ29weVNvdXJjZU9wdGlvbnMpIHtcbiAgICB0aGlzLkJ1Y2tldCA9IEJ1Y2tldFxuICAgIHRoaXMuT2JqZWN0ID0gT2JqZWN0XG4gICAgdGhpcy5WZXJzaW9uSUQgPSBWZXJzaW9uSURcbiAgICB0aGlzLk1hdGNoRVRhZyA9IE1hdGNoRVRhZ1xuICAgIHRoaXMuTm9NYXRjaEVUYWcgPSBOb01hdGNoRVRhZ1xuICAgIHRoaXMuTWF0Y2hNb2RpZmllZFNpbmNlID0gTWF0Y2hNb2RpZmllZFNpbmNlXG4gICAgdGhpcy5NYXRjaFVubW9kaWZpZWRTaW5jZSA9IE1hdGNoVW5tb2RpZmllZFNpbmNlXG4gICAgdGhpcy5NYXRjaFJhbmdlID0gTWF0Y2hSYW5nZVxuICAgIHRoaXMuU3RhcnQgPSBTdGFydFxuICAgIHRoaXMuRW5kID0gRW5kXG4gICAgdGhpcy5FbmNyeXB0aW9uID0gRW5jcnlwdGlvblxuICB9XG5cbiAgdmFsaWRhdGUoKSB7XG4gICAgaWYgKCFpc1ZhbGlkQnVja2V0TmFtZSh0aGlzLkJ1Y2tldCkpIHtcbiAgICAgIHRocm93IG5ldyBlcnJvcnMuSW52YWxpZEJ1Y2tldE5hbWVFcnJvcignSW52YWxpZCBTb3VyY2UgYnVja2V0IG5hbWU6ICcgKyB0aGlzLkJ1Y2tldClcbiAgICB9XG4gICAgaWYgKCFpc1ZhbGlkT2JqZWN0TmFtZSh0aGlzLk9iamVjdCkpIHtcbiAgICAgIHRocm93IG5ldyBlcnJvcnMuSW52YWxpZE9iamVjdE5hbWVFcnJvcihgSW52YWxpZCBTb3VyY2Ugb2JqZWN0IG5hbWU6ICR7dGhpcy5PYmplY3R9YClcbiAgICB9XG4gICAgaWYgKCh0aGlzLk1hdGNoUmFuZ2UgJiYgdGhpcy5TdGFydCAhPT0gLTEgJiYgdGhpcy5FbmQgIT09IC0xICYmIHRoaXMuU3RhcnQgPiB0aGlzLkVuZCkgfHwgdGhpcy5TdGFydCA8IDApIHtcbiAgICAgIHRocm93IG5ldyBlcnJvcnMuSW52YWxpZE9iamVjdE5hbWVFcnJvcignU291cmNlIHN0YXJ0IG11c3QgYmUgbm9uLW5lZ2F0aXZlLCBhbmQgc3RhcnQgbXVzdCBiZSBhdCBtb3N0IGVuZC4nKVxuICAgIH0gZWxzZSBpZiAoKHRoaXMuTWF0Y2hSYW5nZSAmJiAhaXNOdW1iZXIodGhpcy5TdGFydCkpIHx8ICFpc051bWJlcih0aGlzLkVuZCkpIHtcbiAgICAgIHRocm93IG5ldyBlcnJvcnMuSW52YWxpZE9iamVjdE5hbWVFcnJvcihcbiAgICAgICAgJ01hdGNoUmFuZ2UgaXMgc3BlY2lmaWVkLiBCdXQgSW52YWxpZCBTdGFydCBhbmQgRW5kIHZhbHVlcyBhcmUgc3BlY2lmaWVkLicsXG4gICAgICApXG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIGdldEhlYWRlcnMoKTogUmVxdWVzdEhlYWRlcnMge1xuICAgIGNvbnN0IGhlYWRlck9wdGlvbnM6IFJlcXVlc3RIZWFkZXJzID0ge31cbiAgICBoZWFkZXJPcHRpb25zWyd4LWFtei1jb3B5LXNvdXJjZSddID0gZW5jb2RlVVJJKHRoaXMuQnVja2V0ICsgJy8nICsgdGhpcy5PYmplY3QpXG5cbiAgICBpZiAoIWlzRW1wdHkodGhpcy5WZXJzaW9uSUQpKSB7XG4gICAgICBoZWFkZXJPcHRpb25zWyd4LWFtei1jb3B5LXNvdXJjZSddID0gYCR7ZW5jb2RlVVJJKHRoaXMuQnVja2V0ICsgJy8nICsgdGhpcy5PYmplY3QpfT92ZXJzaW9uSWQ9JHt0aGlzLlZlcnNpb25JRH1gXG4gICAgfVxuXG4gICAgaWYgKCFpc0VtcHR5KHRoaXMuTWF0Y2hFVGFnKSkge1xuICAgICAgaGVhZGVyT3B0aW9uc1sneC1hbXotY29weS1zb3VyY2UtaWYtbWF0Y2gnXSA9IHRoaXMuTWF0Y2hFVGFnXG4gICAgfVxuICAgIGlmICghaXNFbXB0eSh0aGlzLk5vTWF0Y2hFVGFnKSkge1xuICAgICAgaGVhZGVyT3B0aW9uc1sneC1hbXotY29weS1zb3VyY2UtaWYtbm9uZS1tYXRjaCddID0gdGhpcy5Ob01hdGNoRVRhZ1xuICAgIH1cblxuICAgIGlmICghaXNFbXB0eSh0aGlzLk1hdGNoTW9kaWZpZWRTaW5jZSkpIHtcbiAgICAgIGhlYWRlck9wdGlvbnNbJ3gtYW16LWNvcHktc291cmNlLWlmLW1vZGlmaWVkLXNpbmNlJ10gPSB0aGlzLk1hdGNoTW9kaWZpZWRTaW5jZVxuICAgIH1cbiAgICBpZiAoIWlzRW1wdHkodGhpcy5NYXRjaFVubW9kaWZpZWRTaW5jZSkpIHtcbiAgICAgIGhlYWRlck9wdGlvbnNbJ3gtYW16LWNvcHktc291cmNlLWlmLXVubW9kaWZpZWQtc2luY2UnXSA9IHRoaXMuTWF0Y2hVbm1vZGlmaWVkU2luY2VcbiAgICB9XG5cbiAgICByZXR1cm4gaGVhZGVyT3B0aW9uc1xuICB9XG59XG5cbi8qKlxuICogQGRlcHJlY2F0ZWQgdXNlIG5vZGVqcyBmcyBtb2R1bGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZURpckFuZEZpbGVzKGRpclBhdGg6IHN0cmluZywgcmVtb3ZlU2VsZiA9IHRydWUpIHtcbiAgaWYgKHJlbW92ZVNlbGYpIHtcbiAgICByZXR1cm4gZnMucm1TeW5jKGRpclBhdGgsIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KVxuICB9XG5cbiAgZnMucmVhZGRpclN5bmMoZGlyUGF0aCkuZm9yRWFjaCgoaXRlbSkgPT4ge1xuICAgIGZzLnJtU3luYyhwYXRoLmpvaW4oZGlyUGF0aCwgaXRlbSksIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KVxuICB9KVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIElDb3B5RGVzdGluYXRpb25PcHRpb25zIHtcbiAgLyoqXG4gICAqIEJ1Y2tldCBuYW1lXG4gICAqL1xuICBCdWNrZXQ6IHN0cmluZ1xuICAvKipcbiAgICogT2JqZWN0IE5hbWUgZm9yIHRoZSBkZXN0aW5hdGlvbiAoY29tcG9zZWQvY29waWVkKSBvYmplY3QgZGVmYXVsdHNcbiAgICovXG4gIE9iamVjdDogc3RyaW5nXG4gIC8qKlxuICAgKiBFbmNyeXB0aW9uIGNvbmZpZ3VyYXRpb24gZGVmYXVsdHMgdG8ge31cbiAgICogQGRlZmF1bHQge31cbiAgICovXG4gIEVuY3J5cHRpb24/OiBFbmNyeXB0aW9uXG4gIFVzZXJNZXRhZGF0YT86IE9iamVjdE1ldGFEYXRhXG4gIC8qKlxuICAgKiBxdWVyeS1zdHJpbmcgZW5jb2RlZCBzdHJpbmcgb3IgUmVjb3JkPHN0cmluZywgc3RyaW5nPiBPYmplY3RcbiAgICovXG4gIFVzZXJUYWdzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB8IHN0cmluZ1xuICBMZWdhbEhvbGQ/OiAnb24nIHwgJ29mZidcbiAgLyoqXG4gICAqIFVUQyBEYXRlIFN0cmluZ1xuICAgKi9cbiAgUmV0YWluVW50aWxEYXRlPzogc3RyaW5nXG4gIE1vZGU/OiBSRVRFTlRJT05fTU9ERVNcbiAgTWV0YWRhdGFEaXJlY3RpdmU/OiAnQ09QWScgfCAnUkVQTEFDRSdcbn1cblxuZXhwb3J0IGNsYXNzIENvcHlEZXN0aW5hdGlvbk9wdGlvbnMge1xuICBwdWJsaWMgcmVhZG9ubHkgQnVja2V0OiBzdHJpbmdcbiAgcHVibGljIHJlYWRvbmx5IE9iamVjdDogc3RyaW5nXG4gIHByaXZhdGUgcmVhZG9ubHkgRW5jcnlwdGlvbj86IEVuY3J5cHRpb25cbiAgcHJpdmF0ZSByZWFkb25seSBVc2VyTWV0YWRhdGE/OiBPYmplY3RNZXRhRGF0YVxuICBwcml2YXRlIHJlYWRvbmx5IFVzZXJUYWdzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB8IHN0cmluZ1xuICBwcml2YXRlIHJlYWRvbmx5IExlZ2FsSG9sZD86ICdvbicgfCAnb2ZmJ1xuICBwcml2YXRlIHJlYWRvbmx5IFJldGFpblVudGlsRGF0ZT86IHN0cmluZ1xuICBwcml2YXRlIHJlYWRvbmx5IE1vZGU/OiBSRVRFTlRJT05fTU9ERVNcbiAgcHJpdmF0ZSByZWFkb25seSBNZXRhZGF0YURpcmVjdGl2ZT86IHN0cmluZ1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBCdWNrZXQsXG4gICAgT2JqZWN0LFxuICAgIEVuY3J5cHRpb24sXG4gICAgVXNlck1ldGFkYXRhLFxuICAgIFVzZXJUYWdzLFxuICAgIExlZ2FsSG9sZCxcbiAgICBSZXRhaW5VbnRpbERhdGUsXG4gICAgTW9kZSxcbiAgICBNZXRhZGF0YURpcmVjdGl2ZSxcbiAgfTogSUNvcHlEZXN0aW5hdGlvbk9wdGlvbnMpIHtcbiAgICB0aGlzLkJ1Y2tldCA9IEJ1Y2tldFxuICAgIHRoaXMuT2JqZWN0ID0gT2JqZWN0XG4gICAgdGhpcy5FbmNyeXB0aW9uID0gRW5jcnlwdGlvbiA/PyB1bmRlZmluZWQgLy8gbnVsbCBpbnB1dCB3aWxsIGJlY29tZSB1bmRlZmluZWQsIGVhc3kgZm9yIHJ1bnRpbWUgYXNzZXJ0XG4gICAgdGhpcy5Vc2VyTWV0YWRhdGEgPSBVc2VyTWV0YWRhdGFcbiAgICB0aGlzLlVzZXJUYWdzID0gVXNlclRhZ3NcbiAgICB0aGlzLkxlZ2FsSG9sZCA9IExlZ2FsSG9sZFxuICAgIHRoaXMuTW9kZSA9IE1vZGUgLy8gcmV0ZW50aW9uIG1vZGVcbiAgICB0aGlzLlJldGFpblVudGlsRGF0ZSA9IFJldGFpblVudGlsRGF0ZVxuICAgIHRoaXMuTWV0YWRhdGFEaXJlY3RpdmUgPSBNZXRhZGF0YURpcmVjdGl2ZVxuICB9XG5cbiAgZ2V0SGVhZGVycygpOiBSZXF1ZXN0SGVhZGVycyB7XG4gICAgY29uc3QgcmVwbGFjZURpcmVjdGl2ZSA9ICdSRVBMQUNFJ1xuICAgIGNvbnN0IGhlYWRlck9wdGlvbnM6IFJlcXVlc3RIZWFkZXJzID0ge31cblxuICAgIGNvbnN0IHVzZXJUYWdzID0gdGhpcy5Vc2VyVGFnc1xuICAgIGlmICghaXNFbXB0eSh1c2VyVGFncykpIHtcbiAgICAgIGhlYWRlck9wdGlvbnNbJ1gtQW16LVRhZ2dpbmctRGlyZWN0aXZlJ10gPSByZXBsYWNlRGlyZWN0aXZlXG4gICAgICBoZWFkZXJPcHRpb25zWydYLUFtei1UYWdnaW5nJ10gPSBpc09iamVjdCh1c2VyVGFncylcbiAgICAgICAgPyBxdWVyeXN0cmluZy5zdHJpbmdpZnkodXNlclRhZ3MpXG4gICAgICAgIDogaXNTdHJpbmcodXNlclRhZ3MpXG4gICAgICAgID8gdXNlclRhZ3NcbiAgICAgICAgOiAnJ1xuICAgIH1cblxuICAgIGlmICh0aGlzLk1vZGUpIHtcbiAgICAgIGhlYWRlck9wdGlvbnNbJ1gtQW16LU9iamVjdC1Mb2NrLU1vZGUnXSA9IHRoaXMuTW9kZSAvLyBHT1ZFUk5BTkNFIG9yIENPTVBMSUFOQ0VcbiAgICB9XG5cbiAgICBpZiAodGhpcy5SZXRhaW5VbnRpbERhdGUpIHtcbiAgICAgIGhlYWRlck9wdGlvbnNbJ1gtQW16LU9iamVjdC1Mb2NrLVJldGFpbi1VbnRpbC1EYXRlJ10gPSB0aGlzLlJldGFpblVudGlsRGF0ZSAvLyBuZWVkcyB0byBiZSBVVEMuXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuTGVnYWxIb2xkKSB7XG4gICAgICBoZWFkZXJPcHRpb25zWydYLUFtei1PYmplY3QtTG9jay1MZWdhbC1Ib2xkJ10gPSB0aGlzLkxlZ2FsSG9sZCAvLyBPTiBvciBPRkZcbiAgICB9XG5cbiAgICBpZiAodGhpcy5Vc2VyTWV0YWRhdGEpIHtcbiAgICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHRoaXMuVXNlck1ldGFkYXRhKSkge1xuICAgICAgICBoZWFkZXJPcHRpb25zW2BYLUFtei1NZXRhLSR7a2V5fWBdID0gdmFsdWUudG9TdHJpbmcoKVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLk1ldGFkYXRhRGlyZWN0aXZlKSB7XG4gICAgICBoZWFkZXJPcHRpb25zW2BYLUFtei1NZXRhZGF0YS1EaXJlY3RpdmVgXSA9IHRoaXMuTWV0YWRhdGFEaXJlY3RpdmVcbiAgICB9XG5cbiAgICBpZiAodGhpcy5FbmNyeXB0aW9uKSB7XG4gICAgICBjb25zdCBlbmNyeXB0aW9uSGVhZGVycyA9IGdldEVuY3J5cHRpb25IZWFkZXJzKHRoaXMuRW5jcnlwdGlvbilcbiAgICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKGVuY3J5cHRpb25IZWFkZXJzKSkge1xuICAgICAgICBoZWFkZXJPcHRpb25zW2tleV0gPSB2YWx1ZVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaGVhZGVyT3B0aW9uc1xuICB9XG5cbiAgdmFsaWRhdGUoKSB7XG4gICAgaWYgKCFpc1ZhbGlkQnVja2V0TmFtZSh0aGlzLkJ1Y2tldCkpIHtcbiAgICAgIHRocm93IG5ldyBlcnJvcnMuSW52YWxpZEJ1Y2tldE5hbWVFcnJvcignSW52YWxpZCBEZXN0aW5hdGlvbiBidWNrZXQgbmFtZTogJyArIHRoaXMuQnVja2V0KVxuICAgIH1cbiAgICBpZiAoIWlzVmFsaWRPYmplY3ROYW1lKHRoaXMuT2JqZWN0KSkge1xuICAgICAgdGhyb3cgbmV3IGVycm9ycy5JbnZhbGlkT2JqZWN0TmFtZUVycm9yKGBJbnZhbGlkIERlc3RpbmF0aW9uIG9iamVjdCBuYW1lOiAke3RoaXMuT2JqZWN0fWApXG4gICAgfVxuICAgIGlmICghaXNFbXB0eSh0aGlzLlVzZXJNZXRhZGF0YSkgJiYgIWlzT2JqZWN0KHRoaXMuVXNlck1ldGFkYXRhKSkge1xuICAgICAgdGhyb3cgbmV3IGVycm9ycy5JbnZhbGlkT2JqZWN0TmFtZUVycm9yKGBEZXN0aW5hdGlvbiBVc2VyTWV0YWRhdGEgc2hvdWxkIGJlIGFuIG9iamVjdCB3aXRoIGtleSB2YWx1ZSBwYWlyc2ApXG4gICAgfVxuXG4gICAgaWYgKCFpc0VtcHR5KHRoaXMuTW9kZSkgJiYgIVtSRVRFTlRJT05fTU9ERVMuR09WRVJOQU5DRSwgUkVURU5USU9OX01PREVTLkNPTVBMSUFOQ0VdLmluY2x1ZGVzKHRoaXMuTW9kZSkpIHtcbiAgICAgIHRocm93IG5ldyBlcnJvcnMuSW52YWxpZE9iamVjdE5hbWVFcnJvcihcbiAgICAgICAgYEludmFsaWQgTW9kZSBzcGVjaWZpZWQgZm9yIGRlc3RpbmF0aW9uIG9iamVjdCBpdCBzaG91bGQgYmUgb25lIG9mIFtHT1ZFUk5BTkNFLENPTVBMSUFOQ0VdYCxcbiAgICAgIClcbiAgICB9XG5cbiAgICBpZiAodGhpcy5FbmNyeXB0aW9uICE9PSB1bmRlZmluZWQgJiYgaXNFbXB0eU9iamVjdCh0aGlzLkVuY3J5cHRpb24pKSB7XG4gICAgICB0aHJvdyBuZXcgZXJyb3JzLkludmFsaWRPYmplY3ROYW1lRXJyb3IoYEludmFsaWQgRW5jcnlwdGlvbiBjb25maWd1cmF0aW9uIGZvciBkZXN0aW5hdGlvbiBvYmplY3QgYClcbiAgICB9XG4gICAgcmV0dXJuIHRydWVcbiAgfVxufVxuXG4vKipcbiAqIG1heWJlIHRoaXMgc2hvdWxkIGJlIGEgZ2VuZXJpYyB0eXBlIGZvciBSZWNvcmRzLCBsZWF2ZSBpdCBmb3IgbGF0ZXIgcmVmYWN0b3JcbiAqL1xuZXhwb3J0IGNsYXNzIFNlbGVjdFJlc3VsdHMge1xuICBwcml2YXRlIHJlY29yZHM/OiB1bmtub3duXG4gIHByaXZhdGUgcmVzcG9uc2U/OiB1bmtub3duXG4gIHByaXZhdGUgc3RhdHM/OiBzdHJpbmdcbiAgcHJpdmF0ZSBwcm9ncmVzcz86IHVua25vd25cblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgcmVjb3JkcywgLy8gcGFyc2VkIGRhdGEgYXMgc3RyZWFtXG4gICAgcmVzcG9uc2UsIC8vIG9yaWdpbmFsIHJlc3BvbnNlIHN0cmVhbVxuICAgIHN0YXRzLCAvLyBzdGF0cyBhcyB4bWxcbiAgICBwcm9ncmVzcywgLy8gc3RhdHMgYXMgeG1sXG4gIH06IHtcbiAgICByZWNvcmRzPzogdW5rbm93blxuICAgIHJlc3BvbnNlPzogdW5rbm93blxuICAgIHN0YXRzPzogc3RyaW5nXG4gICAgcHJvZ3Jlc3M/OiB1bmtub3duXG4gIH0pIHtcbiAgICB0aGlzLnJlY29yZHMgPSByZWNvcmRzXG4gICAgdGhpcy5yZXNwb25zZSA9IHJlc3BvbnNlXG4gICAgdGhpcy5zdGF0cyA9IHN0YXRzXG4gICAgdGhpcy5wcm9ncmVzcyA9IHByb2dyZXNzXG4gIH1cblxuICBzZXRTdGF0cyhzdGF0czogc3RyaW5nKSB7XG4gICAgdGhpcy5zdGF0cyA9IHN0YXRzXG4gIH1cblxuICBnZXRTdGF0cygpIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0c1xuICB9XG5cbiAgc2V0UHJvZ3Jlc3MocHJvZ3Jlc3M6IHVua25vd24pIHtcbiAgICB0aGlzLnByb2dyZXNzID0gcHJvZ3Jlc3NcbiAgfVxuXG4gIGdldFByb2dyZXNzKCkge1xuICAgIHJldHVybiB0aGlzLnByb2dyZXNzXG4gIH1cblxuICBzZXRSZXNwb25zZShyZXNwb25zZTogdW5rbm93bikge1xuICAgIHRoaXMucmVzcG9uc2UgPSByZXNwb25zZVxuICB9XG5cbiAgZ2V0UmVzcG9uc2UoKSB7XG4gICAgcmV0dXJuIHRoaXMucmVzcG9uc2VcbiAgfVxuXG4gIHNldFJlY29yZHMocmVjb3JkczogdW5rbm93bikge1xuICAgIHRoaXMucmVjb3JkcyA9IHJlY29yZHNcbiAgfVxuXG4gIGdldFJlY29yZHMoKTogdW5rbm93biB7XG4gICAgcmV0dXJuIHRoaXMucmVjb3Jkc1xuICB9XG59XG4iXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBS0EsRUFBRTtBQUNkLE9BQU8sS0FBS0MsSUFBSTtBQUVoQixPQUFPLEtBQUtDLFdBQVcs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